//$Id$
/*
 * Copyright (C) 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.apelikecoder.bulgariankeyboard;

import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.preference.PreferenceManager;

public class KeyboardSwitcher implements OnSharedPreferenceChangeListener {

    public static final int MODE_TEXT = 1;
    public static final int MODE_PHONE = 2;
    public static final int MODE_URL = 3;
    public static final int MODE_EMAIL = 4;
    public static final int MODE_IM = 5;
    public static final int MODE_SYMBOLS = 6;

    private static final int KEYBOARDMODE_NORMAL = R.id.mode_normal;
    private static final int KEYBOARDMODE_URL = R.id.mode_url;
    private static final int KEYBOARDMODE_EMAIL = R.id.mode_email;
    private static final int KEYBOARDMODE_IM = R.id.mode_im;

    BulgarianIME mContext;
    private LatinKeyboard mCurrentKeyboard;

    private int mMode;
    private int mImeOptions;
    private boolean mShifted;
    private boolean mSymboled;
    private boolean isDirty;

    private boolean mCyrillicMode;
    private String mCyrillicType;
    private final String kbdTypeKey;

    KeyboardSwitcher(BulgarianIME context) {
        mContext = context;
        mMode = MODE_TEXT;
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
        kbdTypeKey = mContext.getResources().getString(R.string.prefs_kbd_type);
        initCyrillicType(sp);
        sp.registerOnSharedPreferenceChangeListener(this);
    }

    public void clear() {
        mSymboled = false;
        mCurrentKeyboard = null;
    }

    private void initCyrillicType(SharedPreferences sp) {
        mCyrillicType = sp.getString(kbdTypeKey,
                mContext.getString(R.string.default_value_kbd_type));
        BulgarianIME.debug("kbd type is " + mCyrillicType);
    }

    void setCyrillicMode(boolean enable) {
        if (mCyrillicMode != enable) {
            mCyrillicMode = enable;
            isDirty = true;
        }
    }

    boolean isCyrillicMode() {
        return mCyrillicMode;
    }

    private LatinKeyboard makeAlphaKeyboard(int mode) {
        BulgarianIME.debug("KeyboardSwitcher.makeAlphaKeyboard" + "mode "
                + mode + " mCyrillicMode " + mCyrillicMode);
        LatinKeyboard keyboard;
        if (mSymboled) {
            return makeSymbolsKeyboard();
        }
        if (mCyrillicMode) {
            keyboard = makeBulgarianKeyboard(mode);
        } else {
            keyboard = new LatinKeyboard(mContext, R.xml.qwerty, mode);
        }
        keyboard.enableShiftLock();
        return keyboard;
    }

    private BulgarianKeyboardBase makeBulgarianKeyboard(int mode) {
        BulgarianKeyboardBase kbd;
        if (mCyrillicType.equals("bds")) {
            kbd = new BDSKeyboard(mContext, mode);
        } else if (mCyrillicType.equals("phonetic_standard")) {
            kbd = new PhoneticKeyboardStandard(mContext, mode);
        } else {// if (mCyrillicType.equals("phonetic_traditional")) {
            kbd = new PhoneticKeyboardTraditional(mContext, mode);
        }
        return kbd;
    }

    private LatinKeyboard makeSymbolsKeyboard() {
        LatinKeyboard keyboard;
        BulgarianIME.debug( "KeyboardSwitcher.makeSymbolsKeyboard mShifted"
                + mShifted);
        int mode = mCyrillicMode ? R.id.bulgarian_mode : R.id.latin_mode;
        if (mShifted)
            keyboard = new LatinKeyboard(mContext, R.xml.symbols_shift, mode);
        else
            keyboard = new LatinKeyboard(mContext, R.xml.symbols, mode);
        return keyboard;
    }

    private LatinKeyboard makePhoneKeyboard() {
        LatinKeyboard keyboard;
        if (mSymboled)
            keyboard = new PhoneKeyboard(mContext, R.xml.kbd_phone_symbols);
        else
            keyboard = new PhoneKeyboard(mContext, R.xml.kbd_phone);
        return keyboard;
    }

    private LatinKeyboard buildKeyboard() {
        if (!isDirty && mCurrentKeyboard != null) {
            BulgarianIME.debug("cached keyboard found " +  mCurrentKeyboard);
            return mCurrentKeyboard;
        }
        // LatinKeyboard keyboard = (LatinKeyboard) mInputView.getKeyboard();
        // mInputView.setPreviewEnabled(true);
        LatinKeyboard keyboard;
        switch (mMode) {
        default:
        case MODE_TEXT:
            keyboard = makeAlphaKeyboard(KEYBOARDMODE_NORMAL);
            break;
        case MODE_PHONE:
            keyboard = makePhoneKeyboard();
            break;
        case MODE_URL:
            keyboard = makeAlphaKeyboard(KEYBOARDMODE_URL);
            break;
        case MODE_EMAIL:
            keyboard = makeAlphaKeyboard(KEYBOARDMODE_EMAIL);
            break;
        case MODE_IM:
            keyboard = makeAlphaKeyboard(KEYBOARDMODE_IM);
            break;
        }
        // mInputView.setKeyboard(keyboard);
        // keyboard.setShiftLocked(mShifted && keyboard.isShiftLocked());
        keyboard.setImeOptions(mContext.getResources(), mMode, mImeOptions);
        mCurrentKeyboard = keyboard;
        BulgarianIME.debug("buildKeyboard " + keyboard.toString() + "/" + keyboard.getKbdName());
        isDirty = false;
        return keyboard;
    }

    LatinKeyboard getKeyboard(int mode, int imeOptions) {
        BulgarianIME.debug("KeyboardSwitcher.setKeyboardMode " + mode);
        setKeyboardMode(mode);
        setImeOptions(imeOptions);
        return buildKeyboard();
        // keyboard.setShifted(true);
    }

    LatinKeyboard getKeyboard() {
        return buildKeyboard();
    }

    void setKeyboardMode(int mode) {
        if (mMode != mode) {
            isDirty = true;
            if (mMode == MODE_SYMBOLS || mode == MODE_SYMBOLS)
                setSymboled(mode == MODE_SYMBOLS);
            mMode = mode;
        }
    }

    void setImeOptions(int imeOptions) {
        if (mImeOptions != imeOptions) {
            mImeOptions = imeOptions;
            isDirty = true;
        }
    }
    
    void setKeyboardMode(int mode, int imeOptions) {
        setKeyboardMode(mode);
        setImeOptions(imeOptions);
    }

    int getKeyboardMode() {
        return mMode;
    }

    boolean isTextMode() {
        return mMode != MODE_PHONE && !mSymboled;
    }

    boolean isSymbolMode() {
        return mMode != MODE_PHONE && mSymboled;
    }

    public boolean isShifted() {
        return mShifted;
    }

    void toggleShift() {
        BulgarianIME.debug("KeyboardSwitcher.toggleShift " + mShifted);
        mShifted = !mShifted;
        if (!isTextMode()) {
            isDirty = true;
            buildKeyboard();
        }
        mCurrentKeyboard.setShifted(mShifted);
    }

    void toggleSymbols() {
        BulgarianIME.debug("KeyboardSwitcher.toggleSymbols");
        isDirty = true;
        mSymboled = !mSymboled;
        mShifted = false;
        buildKeyboard();
    }

    void setSymboled(boolean symbolsEnabled) {
        if (symbolsEnabled != mSymboled) {
            isDirty = true;
            mSymboled = symbolsEnabled;
        }
    }

    String getKeyboardName() {
        return mCurrentKeyboard != null ? mCurrentKeyboard.getKbdName() : null;
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (key.equals(kbdTypeKey)) {
            initCyrillicType(sharedPreferences);
            isDirty = true;
        }
    }

}
// vim:ts=4:sw=4:expandtab
